from ...pao_python.pao.data import get_string_to_date, get_date, get_string_to_date, get_first_last_day_month, DataProcess
from ...pao_python.pao.service.data.mongo_db import MongoService, MongoFilter, C, N, F, as_date
from ...pao_python.pao.commom import get_data
import pandas as pd
from ...service.buss_pub.bill_manage import BillManageService, OperationType, TypeId, Status
from ...service.mongo_bill_service import MongoBillFilter
from ...service.welfare_institution.accommodation_process import AccommodationProcess
from ...service.buss_mis.service_operation import ServiceOperationService
import datetime


class CostAccount(MongoService):

    def __init__(self, db_addr, db_port, db_name, db_user, db_pwd, inital_password, session):
        DataProcess.__init__(self, db_addr, db_port, db_name, db_user, db_pwd)
        self.inital_password = inital_password
        self.session = session
        self.bill_manage_service = BillManageService(
            db_addr, db_port, db_name, db_user, db_pwd, inital_password, session)
        self.accommodation_process = AccommodationProcess(
            db_addr, db_port, db_name, db_user, db_pwd, inital_password, session)
        self.service_operation_func = ServiceOperationService(
            db_addr, db_port, db_name, db_user, db_pwd, inital_password, session)

    def get_cost_account_list(self, org_list, condition, page, count):
        _filter = MongoBillFilter()
        keys = ['id', 'start_date', 'end_date', 'name', 'cost_status', 'state']
        values = self.get_value(condition, keys)
        if condition.get('start_date') and condition['start_date'] != '':
            _filter.match_bill((C('create_date')) >=
                               as_date(values['start_date']))
        if condition.get('end_date') and condition['end_date'] != '':
            condition['end_date'] = get_string_to_date(
                condition['end_date']) + datetime.timedelta(days=1)
            _filter.match_bill((C('end_date')) < as_date(values['start_date']))
        _filter.match_bill((C('organization_id').inner(org_list)) & (C('cost_status') == None)) \
            .inner_join_bill('PT_Service_Record', 'id', 'id', 'recode')\
               .inner_join_bill('PT_Service_Product', 'service_product_id', 'id', 'product')\
               .inner_join_bill('PT_Service_Item', 'product.service_item_id', 'id', 'item') \
               .project({'product.id': 0, 'item.id': 0})\
               .add_fields({'new_recode': self.ao.merge_objects(['$recode', '$product', '$item'])}) \
               .group({'order_id': '$order_id'}, [{'recode': self.ao.push('$new_recode')}]) \
               .inner_join_bill('PT_Service_Order', 'order_id', 'id', 'order') \
               .inner_join_bill('PT_User', 'order.purchaser_id', 'id', 'user') \
               .match(C('user.name').like(values['name']))\
               .lookup_bill('PT_Bed', 'order.purchaser_id', 'residents_id', 'bed')\
               .project({'_id': 0, 'recode._id': 0, 'product._id': 0, 'item._id': 0, 'new_recode._id': 0, 'user._id': 0, 'order._id': 0, 'bed._id': 0, 'check._id': 0})
        res = self.page_query(_filter, 'PT_Service_Record', page, count)
        return res

    def cost_account(self, condition, select_date, service_operation_func):
        data = get_data(self, 'PT_Service_Record', {}, isList=False)
        flag = OperationType.add.value
        unCostId = []
        query_condition = {}
        res = ''
        # 判断是否该订单已经存在记录，若不存在，则调用接口生成记录
        if len(data['result']):
            ids = data['result']['order_id'].values
            for x in condition:
                if not x in ids:
                    unCostId.append(x)

            self.date_key = [['start_date', 'end_date']]
            date = get_string_to_date(select_date)
            format_date = get_first_last_day_month(date.year, date.month)
            query_condition['start_date'] = get_string_to_date(format_date[0])
            query_condition['end_date'] = get_string_to_date(format_date[1])
            if len(unCostId):
                # 计算水电总数
                values = self.get_value({'ids': unCostId}, ['ids'])
                _filter = MongoBillFilter()
                _filter.lookup_bill('PT_Bed', 'purchaser_id', 'residents_id', 'bed') \
                       .lookup_bill('IEC_Hydropower', 'bed.area_id', 'hotel_id', 'hydropower') \
                       .lookup_bill('PT_Accommodation_Record', 'purchaser_id', 'residents_id', 'recode') \
                       .match_bill((C('id').inner(values['ids']))) \
                       .add_fields({
                           'hydropower_num': self.ao.array_filter('$hydropower', 'recode_', ((F('$recode_.start_date') >= query_condition['start_date']) & (F('$recode_.end_date') <= query_condition['end_date'])).f),
                           'recode_list': self.ao.array_filter('$recode', 'up_', ((F('$up_.checkin_date') >= query_condition['start_date']) | (F('$up_.checkout_date') <= query_condition['end_date'])).f)
                       }) \
                    .add_fields({
                        'electricity_number': {'$sum': '$hydropower_num.electricity_number'},
                        'water_number': {'$sum': '$hydropower_num.water_number'}
                    }) \
                    .project({'_id': 0, 'bed._id': 0, 'hydropower._id': 0, 'hydropower_num._id': 0, 'recode._id': 0, 'recode_list._id': 0})

                res = self.page_query(_filter, 'PT_Service_Order', None, None)
                options = self.__get_accommodation_days(res, query_condition)
                res = []
                table_name = []
                for x in options:
                    data_recode = self.accommodation_process.get_item_info(
                        '住宿', x['id'], x['options'])
                    data_recode.update(
                        start_date=x['checkin_date'], end_date=x['end_date'])
                    res.update(data_recode)
                    recode = self.service_operation_func.add_service_record(
                        data_recode['id'], data_recode['service_product_id'], '0', data_recode)
                    res.append(recode)
                    table_name.append('PT_Service_Record')
                bill_id = self.bill_manage_server.add_bill(
                    flag, TypeId.hydropower.value, data, table_name)
        return 'Success' if bill_id else 'Fail'

    def __get_accommodation_days(self, result, condition):
        days = 0
        options = []
        for res in result['result']:
            for recode in res['recode_list']:
                # 跨月计算
                if recode['checkin_date'] < condition['start_date']:
                    # 若有请假，该记录的实际入住实际为1号到checkout_date
                    days = days + \
                        (recode['checkout_date'].day) if recode['checkout_date'] else (
                            condition['end_date'].day)
                else:
                    days = days + (recode['checkout_date'].day - recode['checkin_date'].day) if recode['checkout_date'] else (
                        condition['end_date'].day - recode['checkin_date'].day)
            options.append({
                'id': res['id'],
                'start_date': recode['checkin_date'],
                'end_date': recode['checkout_date'],
                'options': [{
                    '住宿天数': days,
                    '电费度数': res['electricity_number'],
                    '水费度数':res['water_number']
                }]

            })
        return options
